<template>
  <div>
    <!-- 11 -->
    <CategorySelector :isForbiddenForm="isShowAttrList"></CategorySelector>
    <el-card>
      <div v-if="isShowAttrList">
        <el-button
          :disabled="!categoryStore.category3Id"
          type="primary"
          :icon="Plus"
          @click="toSaveAttrValue"
          >添加属性</el-button
        >
        <el-table
          v-loading="loading"
          :data="attrList"
          border
          style="margin-top: 10px"
        >
          <el-table-column
            label="序号"
            width="80px"
            type="index"
            algin="center"
          ></el-table-column>
          <el-table-column label="属性名称" prop="attrName"> </el-table-column>
          <el-table-column label="属性值列表">
            <template v-slot="{ row }">
              <el-tag
                v-for="attrValue in row.attrValueList"
                :key="attrValue.id"
                style="margin-right: 8px"
                >{{ attrValue.valueName }}</el-tag
              >
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template #default="{ row, $index }">
              <el-button
                title="修改"
                size="small"
                type="warning"
                :icon="Edit"
                @click="toEditAttr(row)"
              />

              <el-popconfirm
                confirm-button-text="确定"
                cancel-button-text="取消"
                :icon="InfoFilled"
                icon-color="#626AEF"
                title="真的确定要删除此条数据么?"
                @confirm="confirmDeleteAttr(row.id)"
              >
                <template #reference>
                  <el-button
                    title="删除"
                    type="danger"
                    size="small"
                    :icon="Delete"
                  />
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div v-else>
        <!-- 这个用的是表单的结构 -->
        <el-form>
          <el-form-item label="属性名" style="width: 300px">
            <el-input
              placeholder="请输入属性名"
              v-model="attrInfo.attrName"
            ></el-input>
          </el-form-item>

          <el-form-item>
            <el-button
              type="primary"
              :disabled="!attrInfo.attrName"
              @click="addAttrValue"
              >添加属性值</el-button
            >
            <!-- <el-button>取消</el-button> -->
          </el-form-item>
        </el-form>

        <!-- 这个用的是表格的结构 -->
        <!-- 将这个对象中的数据绑定到el-table表格上面，这样一有内容，就能生成一行 -->
        <el-table border :data="attrInfo.attrValueList">
          <el-table-column
            label="序号"
            type="index"
            align="center"
            width="80px"
          ></el-table-column>
          <el-table-column label="属性值名称">
            <template v-slot="{ row, $index }">
              <el-input
                ref="inputRef"
                size="small"
                v-model="row.valueName"
                v-if="row.isShowInput"
                @blur="deleteCurrentRow(row, $index)"
              ></el-input>
              <span
                v-else
                @dblclick="toEditAttrValue(row, $index)"
                style="display: inline-block; width: 100%"
                >{{ row.valueName }}
              </span>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template v-slot="{ row, $index }">
              <el-popconfirm
                confirm-button-text="确定"
                cancel-button-text="取消"
                :icon="InfoFilled"
                icon-color="#626AEF"
                title="真的要删除此条属性吗?"
                @confirm="confirmEventAttrValue($index)"
              >
                <template #reference>
                  <el-button
                    title="删除属性"
                    size="small"
                    type="danger"
                    :icon="Delete"
                  ></el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>

        <el-button
          :disabled="!attrInfo.attrValueList.length"
          type="primary"
          @click="saveAttrInfo"
          >保存</el-button
        >
        <el-button type="default" @click="isShowAttrList = true"
          >取消</el-button
        >
      </div>
    </el-card>
  </div>
</template>

<script lang="ts">
import CategorySelector from '@/components/CategorySelector/index.vue'
import { ElMessage } from 'element-plus'

export default {
  name: 'Attr',
  components: { CategorySelector },
}
</script>

<script lang="ts" setup>
import { ref, watch, reactive, nextTick } from 'vue'
import { Plus, Edit, Delete } from '@element-plus/icons-vue'
import { InfoFilled } from '@element-plus/icons-vue'
import { useCategoryListStore } from '@/stores/categoryList'
import {
  reqGetAttrListData,
  reqDeleteOneAttr,
  reqAddOrUpdateAttrInfo,
} from '@/api/product/attr'

// 引入ts类型约束
import type {
  AttrInfoModel,
  AttrListModel,
  AttrValueInfoModel,
} from '@/api/product/model/attrModel'

// 页面中的loading效果
const loading = ref<boolean>(false)

const isShowAttrList = ref<boolean>(true)

// 创建store实例对象
const categoryStore = useCategoryListStore()

// 定义一个属性列表数组 来存储要渲染的数据
const attrList = ref<AttrListModel>([])

// 定义一个变量 为对应输入框 以便用于获取输入框对象
const inputRef = ref<HTMLInputElement>() //HTMLInputElement这个是自带的，专门用来用于input输入框的

// 定义一个添加属性时的属性对象
const attrInfo = reactive<AttrInfoModel>({
  attrName: '', //要添加的属性名
  attrValueList: [], // 要添加的具体的属性值 是一个数组
  categoryId: -1, // 三级分类的id
  categoryLevel: 3, // 分类的等级 当前就设置一个3即可
})

// 1. 获取属性列表的函数  此函数 增加属性 删除属性 获取属性等等都会用到
const getAttrListData = async () => {
  // 请求之前开启loading效果
  loading.value = true

  //在这里统一发送请求来获取数据
  attrList.value = await reqGetAttrListData({
    category1Id: categoryStore.category1Id as number,
    category2Id: categoryStore.category2Id as number,
    category3Id: categoryStore.category3Id as number,
  })
  // 清除loading效果
  loading.value = false
}

// 当三级导航项被选取的时候，此时才需要显示下面的属性列表数据，
// 因为需要监听一下category3Id
// 2. 监听三级导航ID的变化 进而发送请求获取列表数据
watch(
  () => categoryStore.category3Id,
  async (category3Id) => {
    // console.log('监听执行了...',newValue,oldValue)
    if (!category3Id) {
      // 数组列表要清空
      attrList.value = [] // 将数据内容清空，不要显示属性列表了
      return //如果category3Id为空 不要再发送请求了
    }

    // 调用方法，获取属性列表
    getAttrListData()
  },
  // 从别的页面跳转到了当前页面的时候，如果三级导航中有数据的话，需要立即发送请求
  { immediate: true } // 注意此时要开启立即监视，原因就是上面的那个
)

// 3.删除属性
const confirmDeleteAttr = async (id: number) => {
  //发送请求，来将对应id的数据给删除
  await reqDeleteOneAttr(id)
  // 如果删除成功 则要提示用户
  ElMessage.success('删除属性成功...')

  // 重新刷新页面
  getAttrListData()
}

// 4.添加属性
const addAttrValue = () => {
  attrInfo.attrValueList.push({
    valueName: '', // 要添加的具体的属性值
    attrId: attrInfo.id, // 更新的时候才会用到 这一项当前来说可以不写
    isShowInput: true, // 是不是显示输入框 或是显示span标签
  })

  // 让当前的输入框自动获取焦点
  nextTick(() => {
    // 当页面中的数据渲染完毕之后，才让当前的输入框获取焦点
    // nextTick的执行时机，是在页面中的最后一次数据更新完成之后才会执行
    inputRef.value?.focus()
  })
}
// 5. 失去焦点时 删除当前没有属性值的那一项
const deleteCurrentRow = (row: AttrValueInfoModel, index: number) => {
  // 5.1 判断一下当前输入框中是否有值
  if (!row.valueName) {
    // 5.2 如果没有值 则删除当前行
    attrInfo.attrValueList.splice(index, 1)
    return // 不要向下执行了
  }
  // 5.3 如果有值 则失去焦点后要显示span标签 而非el-input
  row.isShowInput = false
}

// 6. 双击span标签修改属性值
const toEditAttrValue = (row: AttrValueInfoModel, index: number) => {
  // 6.1 让输入框显示出来 这样才能更改数据
  row.isShowInput = true
  // 6.2 要让当前输入框获取焦点
  nextTick(() => {
    inputRef.value?.focus()
  })
}

// 7. 删除属性值 也就是删除那一行内容
const confirmEventAttrValue = (index: number) => {
  attrInfo.attrValueList.splice(index, 1)
}

// 8. 添加属性值时，清空原来的旧值
const toSaveAttrValue = () => {
  // 8.1 实现添加属性值时的切换,就是切换到添加的界面
  isShowAttrList.value = false

  // 8.2 清空attrInfo中的数据项
  attrInfo.attrName = ''
  attrInfo.attrValueList = []

  // 清空之前的id 以便保证是正常的添加属性操作
  delete attrInfo.id
}

// 9. 添加属性  或是更新属性，也是执行的这个事件处理程序
const saveAttrInfo = async () => {
  attrInfo.categoryId = categoryStore.category3Id
  await reqAddOrUpdateAttrInfo(attrInfo)

  // 添加成功后，要提示一下用户
  ElMessage.success('操作属性成功...')

  // 切换回属性列表页面
  isShowAttrList.value = true

  // 重新发送请求，获取最新的属性列表数据
  getAttrListData()
}

// 10. 编辑属性之数据回显
const toEditAttr = (row: AttrValueInfoModel) => {
  // 10.1 跳转到添加页面
  isShowAttrList.value = false
  // 10.2 将当前待编辑项显示在页面中 attrInfo
  // attrInfo = row // 不能这样直接赋值
  // console.log('aa', attrInfo)
  // console.log('bb', row)
  Object.assign(attrInfo, row)
}
</script>
<style></style>
